From 98a54f8733a2868590a5127681099beb775711a6 Mon Sep 17 00:00:00 2001 From: "smh22@firebug.cl.cam.ac.uk" Date: Tue, 29 Nov 2005 15:54:44 +0100 Subject: [PATCH] Tidy up audit code for PAE plus avoid its use during live migrate where it is not strictly required. Signed-off-by: Steven Hand --- xen/arch/x86/audit.c | 71 ++++++++++++++++++++++-------------- xen/arch/x86/shadow_public.c | 64 +++++++++++++++++--------------- 2 files changed, 77 insertions(+), 58 deletions(-) diff --git a/xen/arch/x86/audit.c b/xen/arch/x86/audit.c index 16fda1ef6f..5affca0e72 100644 --- a/xen/arch/x86/audit.c +++ b/xen/arch/x86/audit.c @@ -51,7 +51,30 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) int errors = 0; int shadow_refcounts = !!shadow_mode_refcounts(d); int shadow_enabled = !!shadow_mode_enabled(d); - int l2limit; + + int l2limit( unsigned long mfn ) + { + + if ( shadow_mode_external(d) ) + return L2_PAGETABLE_ENTRIES; + +#ifdef __i386__ +#ifdef CONFIG_X86_PAE + /* 32b PAE */ + if ( (( frame_table[mfn].u.inuse.type_info & PGT_va_mask ) + >> PGT_va_shift) == 3 ) + return l2_table_offset(HYPERVISOR_VIRT_START); + else + return L2_PAGETABLE_ENTRIES; +#else + /* 32b non-PAE */ + return DOMAIN_ENTRIES_PER_L2_PAGETABLE; +#endif +#else + /* 64b */ + return 0; /* XXX x86/64 XXX */ +#endif + } void _adjust(struct pfn_info *page, int adjtype ADJUST_EXTRA_ARGS) { @@ -121,15 +144,15 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) void adjust_l2_page(unsigned long mfn, int shadow) { - unsigned long *pt = map_domain_page(mfn); + l2_pgentry_t *pt = map_domain_page(mfn); int i; u32 page_type; - for ( i = 0; i < l2limit; i++ ) + for ( i = 0; i < l2limit(mfn); i++ ) { - if ( pt[i] & _PAGE_PRESENT ) + if ( l2e_get_flags(pt[i]) & _PAGE_PRESENT ) { - unsigned long l1mfn = pt[i] >> PAGE_SHIFT; + unsigned long l1mfn = l2e_get_pfn(pt[i]); struct pfn_info *l1page = pfn_to_page(l1mfn); if ( noisy ) @@ -199,7 +222,7 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) if ( shadow_mode_translate(d) && !shadow_mode_external(d) ) { unsigned long hl2mfn = - pt[l2_table_offset(LINEAR_PT_VIRT_START)] >> PAGE_SHIFT; + l2e_get_pfn(pt[l2_table_offset(LINEAR_PT_VIRT_START)]); struct pfn_info *hl2page = pfn_to_page(hl2mfn); adjust(hl2page, 0); } @@ -209,14 +232,14 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) void adjust_hl2_page(unsigned long hl2mfn) { - unsigned long *pt = map_domain_page(hl2mfn); + l2_pgentry_t *pt = map_domain_page(hl2mfn); int i; - for ( i = 0; i < l2limit; i++ ) + for ( i = 0; i < l2limit(hl2mfn); i++ ) { - if ( pt[i] & _PAGE_PRESENT ) + if ( l2e_get_flags(pt[i]) & _PAGE_PRESENT ) { - unsigned long gmfn = pt[i] >> PAGE_SHIFT; + unsigned long gmfn = l2e_get_pfn(pt[i]); struct pfn_info *gpage = pfn_to_page(gmfn); if ( gmfn < 0x100 ) @@ -256,14 +279,14 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) void adjust_l1_page(unsigned long l1mfn) { - unsigned long *pt = map_domain_page(l1mfn); + l1_pgentry_t *pt = map_domain_page(l1mfn); int i; for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ ) { - if ( pt[i] & _PAGE_PRESENT ) + if ( l1e_get_flags(pt[i]) & _PAGE_PRESENT ) { - unsigned long gmfn = pt[i] >> PAGE_SHIFT; + unsigned long gmfn = l1e_get_pfn(pt[i]); struct pfn_info *gpage = pfn_to_page(gmfn); if ( gmfn < 0x100 ) @@ -280,7 +303,7 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) if ( noisy ) { - if ( pt[i] & _PAGE_RW ) + if ( l1e_get_flags(pt[i]) & _PAGE_RW ) { // If it's not a writable page, complain. // @@ -320,7 +343,7 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) } } - adjust(gpage, (pt[i] & _PAGE_RW) ? 1 : 0); + adjust(gpage, (l1e_get_flags(pt[i]) & _PAGE_RW) ? 1 : 0); } } @@ -544,15 +567,6 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) } } -#ifdef __i386__ - if ( shadow_mode_external(d) ) - l2limit = L2_PAGETABLE_ENTRIES; - else - l2limit = DOMAIN_ENTRIES_PER_L2_PAGETABLE; -#else - l2limit = 0; /* XXX x86/64 XXX */ -#endif - adjust_for_pgtbase(); adjust_guest_pages(); @@ -604,16 +618,17 @@ void _audit_domain(struct domain *d, int flags) unsigned long mfn) { struct pfn_info *page = &frame_table[mfn]; - unsigned long *pt = map_domain_page(mfn); + l1_pgentry_t *pt = map_domain_page(mfn); int i; for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ ) { - if ( (pt[i] & _PAGE_PRESENT) && ((pt[i] >> PAGE_SHIFT) == xmfn) ) + if ( (l1e_get_flags(pt[i]) & _PAGE_PRESENT) && + (l1e_get_pfn(pt[i]) == xmfn) ) printk(" found dom=%d mfn=%lx t=%" PRtype_info " c=%08x " - "pt[i=%x]=%lx\n", + "pt[i=%x]=%" PRIpte "\n", d->domain_id, mfn, page->u.inuse.type_info, - page->count_info, i, pt[i]); + page->count_info, i, l1e_get_intpte(pt[i])); } unmap_domain_page(pt); diff --git a/xen/arch/x86/shadow_public.c b/xen/arch/x86/shadow_public.c index 90ee6f07d6..53abd4c13c 100644 --- a/xen/arch/x86/shadow_public.c +++ b/xen/arch/x86/shadow_public.c @@ -1077,36 +1077,40 @@ int __shadow_mode_enable(struct domain *d, unsigned int mode) // free_shadow_pages(d); - /* - * Tear down its counts by disassembling its page-table-based ref counts. - * Also remove CR3's gcount/tcount. - * That leaves things like GDTs and LDTs and external refs in tact. - * - * Most pages will be writable tcount=0. - * Some will still be L1 tcount=0 or L2 tcount=0. - * Maybe some pages will be type none tcount=0. - * Pages granted external writable refs (via grant tables?) will - * still have a non-zero tcount. That's OK. - * - * gcounts will generally be 1 for PGC_allocated. - * GDTs and LDTs will have additional gcounts. - * Any grant-table based refs will still be in the gcount. - * - * We attempt to grab writable refs to each page (thus setting its type). - * Immediately put back those type refs. - * - * Assert that no pages are left with L1/L2/L3/L4 type. - */ - audit_adjust_pgtables(d, -1, 1); - d->arch.shadow_mode = mode; if ( shadow_mode_refcounts(d) ) { - struct list_head *list_ent = d->page_list.next; - while ( list_ent != &d->page_list ) - { - struct pfn_info *page = list_entry(list_ent, struct pfn_info, list); + struct list_head *list_ent; + + /* + * Tear down its counts by disassembling its page-table-based refcounts + * Also remove CR3's gcount/tcount. + * That leaves things like GDTs and LDTs and external refs in tact. + * + * Most pages will be writable tcount=0. + * Some will still be L1 tcount=0 or L2 tcount=0. + * Maybe some pages will be type none tcount=0. + * Pages granted external writable refs (via grant tables?) will + * still have a non-zero tcount. That's OK. + * + * gcounts will generally be 1 for PGC_allocated. + * GDTs and LDTs will have additional gcounts. + * Any grant-table based refs will still be in the gcount. + * + * We attempt to grab writable refs to each page thus setting its type + * Immediately put back those type refs. + * + * Assert that no pages are left with L1/L2/L3/L4 type. + */ + audit_adjust_pgtables(d, -1, 1); + + + for (list_ent = d->page_list.next; list_ent != &d->page_list; + list_ent = page->list.next) { + + struct pfn_info *page = list_entry(list_ent, + struct pfn_info, list); if ( !get_page_type(page, PGT_writable_page) ) BUG(); put_page_type(page); @@ -1114,14 +1118,14 @@ int __shadow_mode_enable(struct domain *d, unsigned int mode) * We use tlbflush_timestamp as back pointer to smfn, and need to * clean up it. */ - if ( shadow_mode_external(d) ) + if (shadow_mode_external(d)) page->tlbflush_timestamp = 0; - list_ent = page->list.next; } + + audit_adjust_pgtables(d, 1, 1); + } - audit_adjust_pgtables(d, 1, 1); - return 0; nomem: -- 2.30.2